package io.renren.modules.oatools.utils.http;
import com.alibaba.fastjson.JSON;
import org.apache.commons.logging.Log;
import okhttp3.*;
import okio.Buffer;
import org.apache.commons.logging.LogFactory;

import java.io.IOException;
import java.net.URL;
import java.nio.charset.Charset;
import java.sql.Connection;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;

/**
 * 记录日志拦截器
 * 暂时不做重试
 * 错误就记录
 */
public class OAHttpNetworkInvokeIntercepter implements Interceptor {
    private static final Log log = LogFactory.getLog(OAHttpNetworkInvokeIntercepter.class);

    public OAHttpNetworkInvokeIntercepter() {

    }
    public  HttpRequestSend requestSend;

    public OAHttpNetworkInvokeIntercepter(HttpRequestSend requestSend) {
        this.requestSend=requestSend;
    }


    @Override
    public Response intercept(Chain chain) throws IOException {
        log.info("请求拦截");
        Map<String, Object> mapCollect = new HashMap<>();
        long start = System.currentTimeMillis();
        Response response = null;
        String responseBody = null;
        String responseCode = null;
        String url = null;
        String requestBody = null;
        try {
            Request request = chain.request();
            url = request.url().toString();
            requestBody = getRequestBody(request);
            response = chain.proceed(request);
            if (response.body() != null) {
                responseBody = response.body().string();
                responseCode = String.valueOf(response.code());
                MediaType mediaType = response.body().contentType();
                response = response.newBuilder().body(ResponseBody.create(mediaType, responseBody))
                        .build();
            }
        } catch (Exception e) {
            mapCollect.put("error", e.getMessage());
            log.error(e.getMessage());
            e.printStackTrace();
        } finally {
            long end = System.currentTimeMillis();
            String duration = String.valueOf(end - start);
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSSSSS");
            String startDate = dateFormat.format(start);
            String endDate = dateFormat.format(end);
            /**
             * 记录请求日志
             * 请求就报错到数据库
             * 是否重试可以根据字段code、error、response_data 来决定
             */
            mapCollect.put("request_header", chain.request().headers().toString());//请求消息头
            mapCollect.put("request_data", requestBody);//请求参数数据
            mapCollect.put("request_url", url);//请求地址
            mapCollect.put("response_header", null == response ? null : response.headers().toString());//响应数据
            mapCollect.put("response_data", responseBody);//响应数据 报错无数据
//            mapCollect.put("request_num", "1");//请求次数
            mapCollect.put("request_time", startDate);//请求时间
            mapCollect.put("response_time", endDate);//响应时间
            mapCollect.put("response_code", responseCode);//响应码
            mapCollect.put("duration", duration);//耗时毫米
//            mapCollect.put("project_type", projectType);//项目名称
//            mapCollect.put("class_method", classMethod);//类方法
//            mapCollect.put("invoke_name", invokeName);//接口名称
//            mapCollect.put("parent_id", parentId);//父Id
//            mapCollect.put("summary_id", summaryId);//父Id
//            mapCollect.put("serial_number", serialNumber);//父Id
//            mapCollect.put("document_name", documentName);//父Id
//            System.out.println("记录请求日志>>>>>>>>" + mapCollect + "<<<<<<<<<<<<");
            System.out.println("================================================================");
      /*      try {
                Thread.sleep(2002);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }*/
            log.info("请求时间时长毫秒数= " + duration + " ms, 请求地址= " + url + ", 请求参数=" + requestBody + ", 返回状态code= " + responseCode + ", 返回参数= " + responseBody);
            log.info(JSON.toJSONString(mapCollect));
            String insertSQL = "INSERT INTO invoke_interface_log (" +
                    "request_headers," +
                    "request_data," +
                    "request_url," +
                    "response_data," +
//                    "request_num," +
                    "request_time," +
                    "response_time," +
                    "response_code," +
                    "duration," +
                    "project_type," +
                    "class_method," +
                    "invoke_name," +
                    "parent_id," +
                    "summary_id," +
                    "serial_number," +
                    "document_name," +
                    "error) VALUES ("
                    + "'" + mapCollect.get("request_header") + "',"
                    + "'" + mapCollect.get("request_data") + "',"
                    + "'" + mapCollect.get("request_url") + "',"
                    + "'" + mapCollect.get("response_data") + "',"
//                    + "'" + mapCollect.get("request_num") + "',"
                    + "'" + mapCollect.get("request_time") + "',"
                    + "'" + mapCollect.get("response_time") + "',"
                    + "'" + mapCollect.get("response_code") + "',"
                    + "'" + mapCollect.get("duration") + "',"
                    + "'" + mapCollect.get("project_type") + "',"
                    + "'" + mapCollect.get("class_method") + "',"
                    + "'" + mapCollect.get("invoke_name") + "',"
                    + "'" + mapCollect.get("parent_id") + "',"
                    + "'" + mapCollect.get("summary_id") + "',"
                    + "'" + mapCollect.get("serial_number") + "',"
                    + "'" + mapCollect.get("document_name") + "',"
                    + "'" + mapCollect.get("error") + "');";

            try {
                /**
                 * 请求后处理：
                 * 1. 修改请求数据http_request_send
                 * 2. 插入访问日志到http_request_log
                 */
                //插入访问日志到OA系统
//                Boolean result = financeDao.executeBySql(insertSQL);
//                log.info("插入访问日志到OA系统结果= " + result);

//                DruidDataSource ds = new DruidDataSource();
//                ds.setUrl("jdbc:sqlite:D:/OA/code/fy/fe/src/com/seeyon/apps/ext/finance/common/utils/invoke/oa_reflection.db");
//                Connection conn = ds.getConnection();
//                String sql = "INSERT INTO \"http_request_log\" (\"send_id\", \"request_headers\", \"request_params\", \"request_body\", \"request_url\", \"request_time\", \"response_time\", \"response_code\", \"response_data\", \"duration\", \"create_time\") VALUES";
//                sql +=(
//                        "('"+requestSend.getId()+"',"+
//                        "'"+ mapCollect.get("request_header")+"',"+
//                        "'"+ requestSend.getRequestParams()+"',"+
//                        "'"+ requestSend.getRequestBody()+"',"+
//                        "'"+ requestSend.getRequestUrl()+"',"+
//                        "'"+ startDate+"',"+
//                        "'"+ endDate+"',"+
//                        "'"+ responseCode +"',"+
//                        "'"+ responseBody+"',"+
//                        "'"+ duration+"',"+
//                        "datetime())"
//                    );
//                int re = SqlExecutor.execute(conn, sql);
//                log.info(re+"<<<<<<<<<<<<<<<<<<<<<<<<<<");

            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            }
        }
        return response;
    }

//    public String getThisClassPath() {
//        String className = SuperSQLite.class.getName();
//        String classNamePath = className.replace(".", "/") + ".class";
//        URL is = SuperSQLite.class.getClassLoader().getResource(classNamePath);
//        String path = is.getFile();
//        path = StringUtils.replace(path, "%20", " ");
//        StringUtils.removeStart(path, "/");
//        return StringUtils.removeEnd(path, "/SuperSQLite.class");
//
//    }

    private String getRequestBody(Request request) {
        String requestContent = "";
        if (request == null) {
            return requestContent;
        }
        RequestBody requestBody = request.body();
        if (requestBody == null) {
            return requestContent;
        }
        try {
            Buffer buffer = new Buffer();
            requestBody.writeTo(buffer);
            Charset charset = Charset.forName("utf-8");
            requestContent = buffer.readString(charset);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return requestContent;
    }
}